package com.cqie.tes.service.impl.evalute;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.cqie.tes.comm.GlobalConstant;
import com.cqie.tes.comm.R;
import com.cqie.tes.comm.qo.BaseQo;
import com.cqie.tes.comm.service.impl.BaseServiceImpl;
import com.cqie.tes.domain.*;
import com.cqie.tes.domain.qo.tes.evalute.EvaluteQo;
import com.cqie.tes.domain.vo.tes.evalute.AnswerPo;
import com.cqie.tes.domain.vo.tes.evalute.ChooseVo;
import com.cqie.tes.domain.vo.tes.evalute.EvaluteQuestionVo;
import com.cqie.tes.domain.vo.tes.evalute.QuestionItemVo;
import com.cqie.tes.domain.vo.tes.evalute.student.EvaluteStudentOptionVo;
import com.cqie.tes.domain.vo.tes.evalute.student.EvaluteVo;
import com.cqie.tes.mapper.*;
import com.cqie.tes.service.evalute.EvaluteTeacherotherService;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.text.DecimalFormat;
import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * <p>
 *  服务实现类
 * </p>
 *
 * @author DD-GKD
 * @since 2020-09-18
 */
@Slf4j
@Service
public class EvaluteTeacherotherServiceImpl extends BaseServiceImpl<EvalutetaskMapper, Evalutetask> implements EvaluteTeacherotherService {

    @Autowired
    private EvalutetaskMapper evalutetaskMapper;
    @Autowired
    private StudentMapper studentMapper;
    @Autowired
    private ClazzMapper clazzMapper;
    @Autowired
    private EmployeeMapper employeeMapper;
    @Autowired
    private CourseMapper courseMapper;
    @Autowired
    private CourseclazzteacherMapper courseclazzteacherMapper;
    @Autowired
    private EvalutedetailMapper evalutedetailMapper;
    @Autowired
    private EvalutetargetMapper evalutetargetMapper;
    @Autowired
    private TargetitemMapper targetitemMapper;
    @Autowired
    private ResultMapper resultMapper;
    @Autowired
    private DeptMapper deptMapper;

    double testsScore=0;

    /**
     * 教师互评
     * */
    @Override
    public R getList(BaseQo query) {

        EvaluteQo qo = (EvaluteQo) query;
        // volist
        List<EvaluteVo> voList = new ArrayList<>();

        // 根据uid查询教师信息
        if (qo.getId() <= 0 || qo.getId() == null){
            return R.error().message("用户不存在").data("total", 0).data("rows", null);
        }
        QueryWrapper<Employee> fqwstd = new QueryWrapper<>();
        fqwstd.eq("mark", 1);
        fqwstd.eq("userId", qo.getId());
        fqwstd.orderByAsc("id");
        List<Employee> empList = employeeMapper.selectList(fqwstd);
        Employee employee = null;
        if (empList.isEmpty()){
            return R.error().message("教师不存在").data("total", 0).data("rows", null);
        }
        employee = empList.get(0);
        // 根据depti查询d 同事 id列表
        List<Long> ids = employeeMapper.selectList(new QueryWrapper<Employee>()
                .lambda()
                .eq(Employee::getDeptId, employee.getDeptId())
                .ne(Employee::getId,employee.getId())
                .orderByAsc(Employee::getId))
                .stream()
                .map(Employee::getId)
                .collect(Collectors.toList());


        // 根据员工查询课表
//        QueryWrapper<Courseclazzteacher> fqw = new QueryWrapper<>();
//        fqw.eq("mark", 1);
//        fqw.eq("clazzId", clazz.getId());
//        fqw.orderByAsc("id");
        List<Courseclazzteacher> courseclazzteachers = courseclazzteacherMapper.selectList(new QueryWrapper<Courseclazzteacher>()
            .lambda()
            .eq(Courseclazzteacher::getMark,1)
            .in(Courseclazzteacher::getEmpId,ids)
            .orderByAsc(Courseclazzteacher::getId));
        // TODO 待加入去除已评
        // 组织需要评价的列表 -> 去除已评
        // 根据 taskId
        /**
         * -1什么也查不到
         * 传了taskId就根据taskId查
         * 没传就查第一个选项的taskId
         * 如果数据库没有进行中的任务就什么也查不到就是 -1
         * */
        Long taskIdd = -1L; // 从lambda 表达式引用的本地变量必须是最终变量或实际上的
        if (qo.getTaskId() == null){
            R r = optionList();
            if((int)r.getData().get("total") != 0){
                List<EvaluteStudentOptionVo> list = (List) r.getData().get("options");
                taskIdd = list.get(0).getId();
            }
        }else {
            taskIdd = qo.getTaskId();
        }
        Long taskId = taskIdd; // 从lambda 表达式引用的本地变量必须是最终变量或实际上的
        log.info("当前任务Id:{}",taskId);

        courseclazzteachers.forEach(entity -> {
            EvaluteVo vo = new EvaluteVo();

            vo.setTaskId(taskId);
            vo.setClazzId(entity.getClazzId());
            vo.setClazzName(clazzMapper.selectById(entity.getClazzId()).getName());
            vo.setCourseId(entity.getCourseId());
            vo.setCourseName(courseMapper.selectById(entity.getCourseId()).getName());
            vo.setEmployeId(entity.getEmpId());
            vo.setEmployeName(employeeMapper.selectById(entity.getEmpId()).getName());


            // 判断有没有评价过
            // 根据班级id查询课表
            QueryWrapper<Evalutedetail> tqw = new QueryWrapper<>();
            tqw.eq("teacherId", entity.getEmpId());
            tqw.eq("taskId", taskId);
            tqw.eq("courseId", entity.getCourseId());
            tqw.eq("userId", qo.getId());


            List<Evalutedetail> evalutedetailList = evalutedetailMapper.selectList(tqw);
            if (!evalutedetailList.isEmpty()){
                vo.setStatus(1);
            }
            voList.add(vo);
        });

        return R.ok().message("查询成功").data("total", voList.size()).data("rows", voList);
    }

    @Override
    public R getItemList() {
        //学生评教指标
        List<Evalutetarget> targets = evalutetargetMapper.selectList(new QueryWrapper<Evalutetarget>().
                lambda().eq(Evalutetarget::getTypeId, GlobalConstant.TEACHER_ZERO_MUTUAL_TYPE_ID));
        List<EvaluteQuestionVo> voList = new ArrayList<>();
        targets.forEach(x->{
            EvaluteQuestionVo vo = new EvaluteQuestionVo();
            List<Targetitem> items = targetitemMapper.selectList(new QueryWrapper<Targetitem>().
                    lambda().eq(Targetitem::getTargetId, x.getId()).orderByAsc(Targetitem::getSortCode));

            if (!items.isEmpty()){
                List<QuestionItemVo> itemVoList = new ArrayList<>();
                items.forEach(entity->{
                    QuestionItemVo itemVo = new QuestionItemVo();
                    BeanUtils.copyProperties(entity,itemVo);

                    itemVoList.add(itemVo);
                });
                BeanUtils.copyProperties(x,vo);
                vo.setItems(itemVoList);
                voList.add(vo);
            }
        });


        return R.ok().message("查询成功").data("total", voList.size()).data("rows", voList);
    }



    @Override
    public R getItemAnswerList(AnswerPo answerPo) {
        //学生评教指标
        List<Evalutetarget> targets = evalutetargetMapper.selectList(new QueryWrapper<Evalutetarget>().
                lambda().eq(Evalutetarget::getTypeId, GlobalConstant.STUDENT_TYPE_ID));

        List<EvaluteQuestionVo> voList = new ArrayList<>();
        targets.forEach(x->{
            EvaluteQuestionVo vo = new EvaluteQuestionVo();
            List<Targetitem> items = targetitemMapper.selectList(new QueryWrapper<Targetitem>().
                    lambda().eq(Targetitem::getTargetId, x.getId()).orderByAsc(Targetitem::getSortCode));

            if (!items.isEmpty()){
                // TODO 偷懒 查询以前的答案
                Evalutedetail evalutedetail = new Evalutedetail();
                BeanUtils.copyProperties(answerPo,evalutedetail);
                evalutedetail.setTeacherId(Integer.parseInt(answerPo.getEmpId().toString()));
                evalutedetail.setUserId(Integer.parseInt(answerPo.getUserId().toString()));
                evalutedetail.setTaskId(Integer.parseInt(answerPo.getTaskId().toString()));
                // 根据uid查课程
                List<Student> studentList = studentMapper.selectList(new QueryWrapper<Student>().
                        lambda().eq(Student::getUserId, answerPo.getUserId()));
                List<Courseclazzteacher> courseclazzteacherList = courseclazzteacherMapper.selectList(new QueryWrapper<Courseclazzteacher>().
                        lambda().eq(Courseclazzteacher::getEmpId, answerPo.getEmpId()).eq(Courseclazzteacher::getClazzId,studentList.get(0).getClazzId()));
                evalutedetail.setCourseId(Integer.parseInt(courseclazzteacherList.get(0).getCourseId().toString()));



                // 查询答案
                log.info("查询答案开始");
                List<Evalutedetail> detList = evalutedetailMapper.selectList(
                        new QueryWrapper<Evalutedetail>()
                                .lambda()
                                .eq(Evalutedetail::getCourseId, answerPo.getCourseId())
                                .eq(Evalutedetail::getTargetId,x.getId())
                                .eq(Evalutedetail::getTaskId,answerPo.getTaskId())
                                .eq(Evalutedetail::getUserId,answerPo.getUserId())
                                .eq(Evalutedetail::getTeacherId,answerPo.getEmpId()));
                log.info("detList {}",detList);
                if (!detList.isEmpty()){
                    Integer itemId = detList.get(0).getItemId();
                    vo.setAnswer(Long.parseLong(itemId.toString()));
                }



                // =======================
                List<QuestionItemVo> itemVoList = new ArrayList<>();
                items.forEach(entity->{
                    QuestionItemVo itemVo = new QuestionItemVo();
                    BeanUtils.copyProperties(entity,itemVo);




                    itemVoList.add(itemVo);
                });
//                BeanUtils.copyProperties(x,vo);
                vo.setId(x.getId());
                vo.setName(x.getName());
                vo.setItems(itemVoList);
                voList.add(vo);
            }
        });


        return R.ok().message("查询成功").data("total", voList.size()).data("rows", voList);
    }

    // 提交试题结果
    @Transactional
    @Override
    public R saveAnswer(AnswerPo answerPo) {
        // 保存
        Evalutedetail evalutedetail = new Evalutedetail();
        BeanUtils.copyProperties(answerPo,evalutedetail);
        evalutedetail.setTeacherId(Integer.parseInt(answerPo.getEmpId().toString()));
        evalutedetail.setUserId(Integer.parseInt(answerPo.getUserId().toString()));
        evalutedetail.setTaskId(Integer.parseInt(answerPo.getTaskId().toString()));
        // 根据uid查课程
        List<Student> studentList = studentMapper.selectList(new QueryWrapper<Student>().
                lambda().eq(Student::getUserId, answerPo.getUserId()));
        List<Courseclazzteacher> courseclazzteacherList = courseclazzteacherMapper.selectList(new QueryWrapper<Courseclazzteacher>().
                lambda().eq(Courseclazzteacher::getEmpId, answerPo.getEmpId()).eq(Courseclazzteacher::getClazzId,studentList.get(0).getClazzId()));
        evalutedetail.setCourseId(Integer.parseInt(courseclazzteacherList.get(0).getCourseId().toString()));

        answerPo.getChooseVoList().forEach(choose->{
            evalutedetail.setTargetId(choose.getTargetId());
            evalutedetail.setItemId(choose.getTargetItemId());
            evalutedetailMapper.insert(evalutedetail);
            log.info("保存答案:{}",evalutedetail);
        });

        // 准备数据
        double score = 1;
//        double testsScore=0;
        List<Integer> ids = answerPo.getChooseVoList().stream().map(ChooseVo::getTargetId).collect(Collectors.toList());
            //所有叶子节点
        List<Evalutetarget> evaluteTargets = evalutetargetMapper.selectBatchIds(ids);
        Integer typeId = evaluteTargets.get(0).getTypeId();
        Long taskId = answerPo.getTaskId();
        Long teacherId = answerPo.getEmpId();
        // 计算分数

        getChildAndScore(evaluteTargets, score, answerPo.getChooseVoList(),Long.parseLong(typeId.toString()));
        // 保存分数
        DecimalFormat df=new DecimalFormat("0.00");
        Result evaluteResult = new Result();
        evaluteResult.setScore( Double.parseDouble(df.format(testsScore)));
        evaluteResult.setTaskId(Math.toIntExact(taskId));
        evaluteResult.setTeacherId(Math.toIntExact(teacherId));
        evaluteResult.setTypeId(typeId);
        resultMapper.insert(evaluteResult);

        return R.ok();
    }

    @Override
    public R optionList() {


        // 结果列表
        List<EvaluteStudentOptionVo> vos  =new ArrayList<>();

        Date now  = new Date();
        QueryWrapper<Evalutetask> qw = new QueryWrapper<>();
        qw.eq("mark", 1);
        qw.le("start", now);
        qw.ge("end", now);
        qw.orderByAsc("id");

        List<Evalutetask> entityList = evalutetaskMapper.selectList(qw);
        entityList.forEach(entity->{
            EvaluteStudentOptionVo vo = new EvaluteStudentOptionVo();
            BeanUtils.copyProperties(entity,vo);
            vos.add(vo);

            log.warn("正在进行任务:{}",entity);

        });
        return R.ok().message("查询成功").data("total",vos.size()).data("options", vos);
    }

    /**
     * 递归算分(从叶子节点回退)
     * 叶子节点指标列表
     * score 临时分
     * recordList TargetitemVo 指标选项
     * typeId 评教类型
     */
    private void getChildAndScore(List<Evalutetarget> list, double score, List<ChooseVo> recordList,Long typeId) {
        for (Evalutetarget x : list) {
            double y;
            //找到节点对应记录
            boolean flag = recordList.get(0).getTargetId().equals(x.getId());
            List<ChooseVo> boys = recordList.stream().filter(s -> s.getTargetId().intValue() == x.getId()).collect(Collectors.toList());
            if (boys.size() != 0){
                Integer itemId = boys.get(0).getTargetItemId();
                //对应选项
                Targetitem byId = targetitemMapper.selectById(itemId);
                y= x.getWeight()*byId.getScore();
            }else {
                y= x.getWeight()*score;
            }
            //同级对象
            List<Evalutetarget> listOne = evalutetargetMapper.selectList(new QueryWrapper<Evalutetarget>().
                    lambda().eq(Evalutetarget::getParentId, x.getParentId()).
                    eq(Evalutetarget::getTypeId,typeId));
            //同级权之和
            double denominator=0;
            for (Evalutetarget target : listOne) {
                denominator+=target.getWeight();
            }
            score=(y/denominator);
            //获取父级
            List<Evalutetarget> listTwo = evalutetargetMapper.selectList(new QueryWrapper<Evalutetarget>().
                    lambda().eq(Evalutetarget::getId, x.getParentId()));
            if (listTwo.size() != 0){
                //有父级则进入父级
                getChildAndScore(listTwo,score,recordList,typeId);
            }else {
                //每层求和
                testsScore += score;
            }

        }

    }

}

